<?php



class Image extends LibBase{
	
	private $handle = null;
	private $size = null;
	private $mime = null;
	
	
	public function __construct($filepath){
		if(!file_exists($filepath)){
			throw new PException("文件不存在");
		}
		//读取图片
		$this->size = @getimagesize($filepath);
		if(FALSE==$this->size){
			throw new PException("图片地址错误");
		}
		//读取旧图片
		switch ($this->size[2]) {
			case 1:
				$this->mime = 'image/gif';
				$this->handle = @imagecreatefromgif($filepath);break;
			case 2:
				$this->mime = 'image/jpeg';
				$this->handle = @imagecreatefromjpeg($filepath);break;
			case 3:
				$this->mime = 'image/png';
				$this->handle = @imagecreatefrompng($filepath);break;
			default:
				throw new PException("找不到图片");
		}

		
	}
	
	public function getSize(){
		return array('width'=>$this->size[0],'height'=>$this->size[1]);
	}

	public function rgb2hsl($r,$g,$b){
	
	    $var_r = ( $r / 255 );
	    $var_g = ( $g / 255 );
	    $var_b = ( $b / 255 );
	
	    $var_Min = min( $var_r, $var_g, $var_b );
	    $var_Max = max( $var_r, $var_g, $var_b );
	    $del_Max = $var_Max - $var_Min;
	
	    $l = ( $var_Max + $var_Min ) / 2;
	
	    if ( $del_Max == 0 )
	    {
	       $h = 0;
	       $s = 0;
	    }
	    else
	    {
	        if ( $l < 0.5 )
	        {
	            $s = $del_Max / ( $var_Max + $var_Min );
	        }
	        else
	        {
	            $s = $del_Max / ( 2 - $var_Max - $var_Min );
	        }
	
	        $del_R = ( ( ( $var_Max - $var_r ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
	        $del_G = ( ( ( $var_Max - $var_g ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
	        $del_B = ( ( ( $var_Max - $var_b ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
	
	        if ( $var_r == $var_Max )
	        {
	            $h = $del_B - $del_G;
	        }
	        else if ( $var_g == $var_Max )
	        {
	            $h = ( 1 / 3 ) + $del_R - $del_B;
	        }
	        else if ( $var_b == $var_Max )
	        {
	            $h = ( 2 / 3 ) + $del_G - $del_R;
	        }
	
	        if ( $h < 0 )
	        {
	            $h += 1;
	        }
	        if ( $h > 1 )
	        {
	            $h -= 1;
	        }
	
	    }
	
	    return array( $h, $s, $l );
	
			
	}
	public function hsl2rgb($h,$s,$l){
	    if ( $s == 0 ){
	        $r = $l * 255;
	        $g = $l * 255;
	        $b = $l * 255;
	    }else{
	        if ( $l < 0.5 ){
	            $var_2 = $l * ( 1 + $s );
	        }else{
	            $var_2 = ( $l + $s ) - ( $s * $l );
	        }
	
	        $var_1 = 2 * $l - $var_2;
//	echo $var_1.':'.$var_2.":".$h."<br>";
	        $r = 255 * $this->hue2rgb( $var_1, $var_2, $h + ( 1 / 3 ) );
	        $g = 255 * $this->hue2rgb( $var_1, $var_2, $h );
	        $b = 255 * $this->hue2rgb( $var_1, $var_2, $h - ( 1 / 3 ) );
	    }
//	echo $r.':'.$g.":".$b."<br>";
	    return array( ceil($r), ceil($g), ceil($b) );
	
			
	}
	
	private function hue2rgb($v1,$v2,$vh){
	
	    if ( $vh < 0 ){
	        $vh += 1;
	    }
	    if ( $vh > 1 ){
	        $vh -= 1;
	    }
	    if ( ( 6 * $vh ) < 1 ){
	        return ( $v1 + ( $v2 - $v1 ) * 6 * $vh );
	    }
	    if ( ( 2 * $vh ) < 1 ){
	        return ( $v2 );
	    }
	    if ( ( 3 * $vh ) < 2 ){
	        return ( $v1 + ( $v2 - $v1 ) * ( ( 2 / 3 ) - $vh ) * 6 );
	    }
	    return ( $v1 );
	}
	
	public function hsl255($val){
		return 255*$val;
	}

	public function color2rgb($color) {
		return str_pad(base_convert($color, 10, 16), 6, 0, STR_PAD_LEFT);
	}
	public function rgb2array($rgb) {
		return array(
			base_convert(substr($rgb, 0, 2), 16, 10),
			base_convert(substr($rgb, 2, 2), 16, 10),
			base_convert(substr($rgb, 4, 2), 16, 10),
		);
 }
 

	/**
	 * <p>以box的方式保持比例的创建缩略图，支持gif、jpg、png文件</p>
	 * 
	 * @return true,false - 是否成功创建bool
	 * @param $src string - 源图片的路径
	 * @param $dst string - 目标图片的路径
	 * @param $w string - 目标图片的宽度
	 * @param $h string - 目标图片的高度
	 */
	public function boxResize($w,$h){
		
		if(!empty($output) && !is_readable($output)){
			throw new PException("目录不可读");
		}		
		
		//确定真实的目标的宽高		
		if($this->size[0]/$this->size[1] > $w/$h){
			$h = round($w*$this->size[1]/$this->size[0]);
		}else{
			$w = round($h*$this->size[0]/$this->size[1]);
		}
		
		//创建新图片
		$im = @imagecreatetruecolor($w,$h);
		
		//将旧图片按照新的大小复制到新图片中
		if(!imagecopyresampled($im,$this->handle,0,0,0,0,$w,$h,$this->size[0],$this->size[1]))
			return false;
		$this->handle = $im;
	}
	
	/**
	 * <p>以box的方式保持比例的创建缩略图，支持gif、jpg、png文件</p>
	 * <p>生成$maxheight*$maxheight大小图片，按照原图等比例缩放到$maxheight*$maxheight背景上</p>
	 * <p>如果图片的比例和$maxheight/$maxheight比例不同，采用上下留白/左右留白</p>
	 * 
	 * @return true,false - 是否成功创建bool
	 * @param $src string - 源图片的路径
	 * @param $dst string - 目标图片的路径
	 * @param $w string - 目标图片的宽度
	 * @param $h string - 目标图片的高度
	 */
	function boxResize2($maxwidth,$maxheight,$bg){
		
		
		//创建新图片
		$im	= imagecreatetruecolor($maxwidth,$maxheight);//生成一张要生成的黑色背景图 ，比例为计算出来的新图片比例
//		$white	= imagecolorallocate($dst_im, 255, 255, 255);//为一幅图像分配白色

		$rgbArr = $this->rgb2array($bg);
		$color	= imagecolorallocate($im, $rgbArr[0], $rgbArr[1], $rgbArr[2]);
		
		imagefilledrectangle($im,0,0,$maxwidth,$maxheight,$color);//填充背景色

		/**
		 *计算图片缩放
		 *把图投影到背景图中间，计算top坐标
		 */
		$x = 0;
		$y = 0;
		$c_width	= $maxwidth;
		$c_height	= $maxheight;
		//按长边缩放
		if($this->size[0]/$this->size[1] > $maxwidth/$maxheight){//按宽度缩放上下部留白
			$c_height = round($c_width*$this->size[1]/$this->size[0]);
			$y		  = round(abs($maxheight-$c_height)/2);
		}else{//按高度缩放左右留白
			$c_width = round($c_height*$this->size[0]/$this->size[1]);
			$x = round(abs($maxwidth-$c_width)/2);
		}

		//复制按比例缩放的原图到 ，新的背景中。
		if(!imagecopyresampled($im,$this->handle,$x,$y,0,0,$c_width,$c_height,$this->size[0],$this->size[1]))
			return false;
		
		$this->handle = $im;
		
	}


	/**
	 * <p>以box的方式保持比例的创建缩略图，支持gif、jpg、png文件</p>
	 * <p>生成$maxheight*$maxheight大小图片，按照原图等比例缩放到$maxheight*$maxheight背景上</p>
	 * <p>如果图片的比例和$maxheight/$maxheight比例不同，采用上下留白/左右留白</p>
	 * 
	 * @return true,false - 是否成功创建bool
	 * @param $src string - 源图片的路径
	 * @param $dst string - 目标图片的路径
	 * @param $w string - 目标图片的宽度
	 * @param $h string - 目标图片的高度
	 */
	function boxResize3($miniwidth,$miniheight){


		if($this->size[0]/$this->size[1] < $miniwidth/$miniheight){//按宽度缩放上下部留白
			$c_height = round($miniwidth*$this->size[1]/$this->size[0]);
			$this->boxResize($miniwidth, $c_height);
		}else{//按高度缩放左右留白
			$c_width = round($miniheight*$this->size[0]/$this->size[1]);
			$this->boxResize($c_width, $miniheight);
		}

		//创建新图片
		$im	= imagecreatetruecolor($miniwidth,$miniheight);//生成一张要生成的黑色背景图 ，比例为计算出来的新图片比例
//		$white	= imagecolorallocate($dst_im, 255, 255, 255);//为一幅图像分配白色

		$x = round(($this->size[0]-$miniwidth)/2);
		$y = round(($this->size[1]-$miniheight)/2);
		//按长边缩放

		imagecopy($im,$this->handle,0,0,$x,$y,$miniwidth,$miniheight);

		
		$this->handle = $im;
		$this->size[0] = imagesx($miniwidth);//裁剪后尺寸发生了变化。需要更新图片的尺寸值
		$this->size[1] = imagesy($miniheight);
		
	}



	/**
	 * 图片旋转
	 */
	public function rotate($degrees,$bgStr='000000'){
	
		//$im	= imagecreatetruecolor($maxwidth,$maxheight);//生成一张要生成的黑色背景图 ，比例为计算出来的新图片比例

// Output
		$size = $this->getSize();
		//创建新图片
		$im	= imagecreatetruecolor($size['width'],$size['height']);//创建底板
		
		$rgb = $this->rgb2array($bgStr);
		$bgColor = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);//创建背景颜色
		
		$this->handle = imagerotate($this->handle,$degrees,$bgColor);//旋转
		$this->size[0] = imagesx($this->handle);//旋转后尺寸发生了变化。需要更新图片的尺寸值
		$this->size[1] = imagesy($this->handle);
	}


	/**
	 * 水平及垂直翻转。
	 * 
	 * $xy string 	如果字符串中存在x则水平翻转，如果存在y则垂直翻转。
	 */
	public function reversal($xy){
		
		$size = $this->getSize();
		$xy = strtolower($xy);
		if(FALSE!==strpos($xy, 'x')){
			$new=imagecreatetruecolor($size['width'], $size['height']);
			for($x=0; $x < $size['width']; $x++){
				imagecopy($new, $this->handle, $size['width']-$x-1, 0, $x, 0, 1, $size['height']);
			}
			$this->handle = $new;
			
		}

		if(FALSE!==strpos($xy, 'y')){
			$new=imagecreatetruecolor($size['width'], $size['height']);
			for($y=0; $y < $size['height']; $y++){
				imagecopy($new, $this->handle,0, $size['height']-$y-1, 0, $y, $size['width'], 1);
			}
			$this->handle = $new;
		}

	}
	
	public function cut($x,$y,$w,$h){
		$x = intval($x);
		$y = intval($y);
		$w = intval($w);
		$h = intval($h);
		
		$size = $this->getSize();
		$w = empty($w)?($size['width']-$x):$w;
		$h = empty($h)?($size['height']-$y):$h;
		$new=imagecreatetruecolor($w, $h);
		imagecopy($new,$this->handle,0,0,$x,$y,$w,$h);
		$this->handle = $new;
		$this->size[0] = imagesx($w);//裁剪后尺寸发生了变化。需要更新图片的尺寸值
		$this->size[1] = imagesy($h);
		
		
	}

	public function iprint($output=''){
		
		if(empty($output)){
			header("Content-type: {$this->mime}");
			imagepng($this->handle);
			
		}else{
			//保存图片到磁盘,不管上传什么图片都处理成jpg
			if(!imagejpeg($this->handle,$output,100))
				throw new PException("保存文件异常");
			//清理内存
			@imagedestroy($this->handle);
			
		}
		
	}
	
}
